import 'dart:collection';
import 'dart:io';

import '../error/result.dart';
import 'work.dart' show sp1;
import 'interface.dart';

/**
 *   PACKAGE:
 *   USER:Administrator
 *   TIME:2021/1/3 0003 13:05
 *   Description:全局内核参数
 */
File yyFile;
List code;
int code_len; //代码总长度
int current_posL = 0; //当前分析列的位置
int current_posH = 1; //当前分析行的位置
int current_pos = 0; //当前分析的位置
int current_char = 0; //当前分析的字符

void sendErrorMsgToMain(code, msg, data) =>
    sp1.send(Result.iso(code, msg, data));

enum ExpressionType {
  BOOLEAN_EXPRESSION,
  INT_EXPRESSION,
  DOUBLE_EXPRESSION,
  STRING_EXPRESSION,
  REGEXP_EXPRESSION,
  IDENTIFIER_EXPRESSION,
  GLOBAL_EXPRESSION,
  COMPLEX_EXPRESSION,
  COMMA_EXPRESSION,
  ASSIGN_EXPRESSION,
  ADD_EXPRESSION,
  SUB_EXPRESSION,
  MUL_EXPRESSION,
  DIV_EXPRESSION,
  MOD_EXPRESSION,
  DOT_DIV_EXPRESSION,
  DOT_MUL_EXPRESSION,
  BIT_AND_EXPRESSION,
  BIT_OR_EXPRESSION,
  BIT_XOR_EXPRESSION,
  EQ_EXPRESSION,
  NE_EXPRESSION,
  GT_EXPRESSION,
  GE_EXPRESSION,
  LT_EXPRESSION,
  LE_EXPRESSION,
  LOGICAL_AND_EXPRESSION,
  LOGICAL_OR_EXPRESSION,
  MINUS_EXPRESSION,
  BIT_NOT_EXPRESSION,
  LOGICAL_NOT_EXPRESSION,
  FUNCTION_CALL_EXPRESSION,
  NULL_EXPRESSION,
  ARRAY_EXPRESSION,
  INDEX_EXPRESSION,
  INCREMENT_EXPRESSION,
  DECREMENT_EXPRESSION,
  MODULE_CALL_EXPRESSION,
  EXPRESSION_TYPE_COUNT_PLUS_1
}

///编译器支持的基本数据类型，[todo]待添加
enum ValueType {
  BOOLEAN_VALUE,
  INT_VALUE,
  DOUBLE_VALUE,
  STRING_VALUE,
  REGEXP_VALUE,
  COMPLEX_VALUE,
  ARRAY_VALUE,
  NULL_VALUE,
  FUNCTION_VALUE,
  NATIVE_POINTER_VALUE,
}

//复数类
class Complex {
  var a;
  var b;
  Complex(this.a, this.b);
  @override
  String toString() {
    if (a == 0) {
      return "${b.toString()}i";
    } else
      return b > 0
          ? "${a.toString()} + ${b.toString()}i"
          : "${a.toString() + b.toString()}i";
  }

  @override
  bool operator ==(Object other) {
    if ((other is Complex) && (a == other.a) && (b == other.b)) {
      return true;
    }
    return false;
  }
}

enum StatementType {
  EXPRESSION_STATEMENT,
  CONST_STATEMENT,
  BLOCK_STATEMENT,
  IF_STATEMENT,
  WHILE_STATEMENT,
  FOR_STATEMENT,
  RETURN_STATEMENT,
  BREAK_STATEMENT,
  CONTINUE_STATEMENT,
  SWITCH_STATEMENT,
  TRY_STATEMENT,
  STATEMENT_TYPE_COUNT_PLUS_1
}

class Value extends LinkedListEntry<Value> {
  ValueType type;
  dynamic value;
  String module; //给模块调用表达式使用
  Value(this.type, this.value, {this.module});
  @override
  String toString() {
    ///" type:" + type.toString() + " value:" + value.toString();
    return value.toString();
  }

  @override
  bool operator ==(Object other) {
    if (other is Value) {
      if ((type == other.type) && (value == other.value)) {
        return true;
      }
    }
    return false;
  }
}

class CommaExpression {
  Expression left;
  Expression right;
}

enum AssignmentOperator {
  NORMAL_ASSIGN,
  ADD_ASSIGN,
  SUB_ASSIGN,
  MUL_ASSIGN,
  DIV_ASSIGN,
  MOD_ASSIGN,
  BIT_XOR_ASSIGN,
  BIT_AND_ASSIGN,
  BIT_OR_ASSIGN,
}

class AssignExpression {
  AssignmentOperator operator;
  Expression left;
  Expression operand;
}

class BinaryExpression {
  Expression left;
  Expression right;
}

class ArgumentList extends LinkedListEntry<ArgumentList> {
  Expression expression;
  ArgumentList(this.expression);
}

class FunctionCallExpression {
  Expression function;
  LinkedList<ArgumentList> argument;
  FunctionCallExpression() {
    argument = LinkedList();
  }
}

class IndexExpression {
  Expression array;
  Expression index;
}

class IncrementOrDecrement {
  Expression operand;
}

//数组类
class Array {
  List<LinkedList<Expression>> array;
  Array() {
    array = List();
  }
}

class ArrayValue {
  List<LinkedList<Value>> array;
  int _length;
  int hang;
  List<int> lie;
  ArrayValue() {
    array = List();
    _length = 0;
    hang = 0;
    lie = List();
  }
  int get length => _length;

  set length(length) => this._length = length;

  @override
  String toString() {
    if (array.isEmpty) {
      return "[]";
    } else {
      String t1 = "[";
      array.forEach((e) {
        e.forEach((entry) {
          t1 += entry.toString() + ",";
        });
        t1 += ";";
      });
      t1 += "]";
      t1 = t1.replaceAll(",;", ";");
      t1 = t1.replaceAll(";]", "]");
      return t1;
    }
  }

  @override
  bool operator ==(Object other) {
    if (other is ArrayValue) {
      if (array.isEmpty) {
        return other.array.isEmpty;
      } else {
        if (array.length != other.array.length) return false;

        for (var j = 0; j < array.length; j++) {
          var f = other.array[j].first;
          for (var i = array[j].first; i != null; i = i.next) {
            if ((i.type == f.type) && (i.value == f.value)) {
              f = f.next;
            } else {
              return false;
            }
          }
        }
        return true;
      }
    }
    return false;
  }
}

class Expression extends LinkedListEntry<Expression> {
  ExpressionType type;
  bool bool_value;
  int int_value;
  double double_value;
  String string_value;
  String regexp_value;
  String identifier;
  String module;
  CommaExpression comma = CommaExpression();
  AssignExpression assign_expression = AssignExpression();
  BinaryExpression binary_expression = BinaryExpression();
  Expression minus_expression;
  FunctionCallExpression function_call_expression = FunctionCallExpression();
  Array array = Array();
  IndexExpression index_expression = IndexExpression();
  IncrementOrDecrement inc_dec = IncrementOrDecrement();
  @override
  String toString() {
    return "ExpressionType:$ExpressionType ";
  }
}

///变量类，定义后变量名不可更改，值可以
class Variable extends LinkedListEntry<Variable> {
  final String name;
  final bool isFixed;

  ///是否常量
  Value value;
  Variable(this.name, this.value, this.isFixed);
  @override
  String toString() {
    return " name:" +
        name.toString() +
        " isFixed:" +
        isFixed.toString() +
        " value:" +
        value.toString();
  }
}

class IdentifierList extends LinkedListEntry<IdentifierList> {
  final Expression expression;
  IdentifierList(this.expression);
}

///常量
class ConstStatement {
  LinkedList<IdentifierList> identifier_list;
  ConstStatement() {
    identifier_list = LinkedList();
  }
}

class Elsif extends LinkedListEntry<Elsif> {
  Expression condition;
  Block block;
  Elsif(this.condition, this.block);
}

class IfStatement {
  Expression condition;
  Block then_block;
  LinkedList<Elsif> elsif_list;
  Block else_block;
  IfStatement() {
    condition = Expression();
    then_block = Block();
  }
}

class WhileStatement {
  Expression condition;
  Block block;
  WhileStatement() {
    condition = Expression();
    block = Block();
  }
}

class ForStatement {
  Expression init;
  Expression condition;
  Expression post;
  Block block;
  ForStatement() {
    init = Expression();
    condition = Expression();
    post = Expression();
    block = Block();
  }
}

class ReturnStatement {
  Expression return_value;
  ReturnStatement() {
    return_value = Expression();
  }
}

class CaseList extends LinkedListEntry<CaseList> {
  LinkedList<Expression> expression_list;
  Block block;
  CaseList();
}

class SwitchStatement {
  Expression expression;
  LinkedList<CaseList> case_list;
  Block default_block;
  SwitchStatement() {
    expression = Expression();
  }
}

class TryStatement {
  Block try_block;
  Block catch_block;
  Block finally_block;
  final String exception;
  TryStatement(this.exception);
}

class BlockStatement {
  Block block;
  BlockStatement(this.block) {}
}

class Statement extends LinkedListEntry<Statement> {
  StatementType type;
  int line_number;
  Statement() {
    expression_s = Expression();
    const_s = ConstStatement();
    if_s = IfStatement();
    while_s = WhileStatement();
    for_s = ForStatement();
    return_s = ReturnStatement();
    switch_s = SwitchStatement();
    block_s = BlockStatement(null);
  }
  Expression expression_s;
  ConstStatement const_s;
  IfStatement if_s;
  WhileStatement while_s;
  ForStatement for_s;
  ReturnStatement return_s;
  SwitchStatement switch_s;
  TryStatement try_s;
  BlockStatement block_s;
  @override
  String toString() {
    // TODO: implement toString
    return " StatementType:" +
        type.toString() +
        " line:" +
        line_number.toString();
  }
}

class Block {
  LinkedList<Statement> statement_list;
  Block();
}

class Parameter extends LinkedListEntry<Parameter> {
  final String name;
  Parameter(this.name);
}

///内置函数定义
typedef Value NativeFunctionProc(List<Value> args);

///函数定义类
class FunctionDefinition extends LinkedListEntry<FunctionDefinition> {
  final String name;

  final bool isNative;

  LinkedList<Parameter> parameter = LinkedList(); //参数列表

  Block block; //函数主体

  NativeFunctionProc proc; //内置函数

  FunctionDefinition(this.name, this.isNative);

  @override
  String toString() {
    // TODO: implement toString
    return " Function:" + name;
  }
}

enum StatementResultType {
  NORMAL_STATEMENT_RESULT,
  RETURN_STATEMENT_RESULT,
  BREAK_STATEMENT_RESULT,
  CONTINUE_STATEMENT_RESULT,
  ERROR_RUNTIME_RESULT,
  STATEMENT_RESULT_TYPE_COUNT_PLUS_1
}

class StatementResult {
  StatementResultType type;
  Value return_value;
  String error;
  StatementResult() {
    return_value = Value(null, null);
    type = StatementResultType.NORMAL_STATEMENT_RESULT;
  }
  @override
  String toString() {
    return this.error;
  }
}
